/*拾色器
 * @Author: kevin.huang 
 * @Date: 2018-07-21 12:54:06 
 * @Last Modified by: kevin.huang
 * @Last Modified time: 2019-03-23 19:54:42
 * Copyright (c): kevin.huang Released under MIT License
 */
(function (global, factory) {
    if (typeof define === 'function' && define.amd  && !window["_all_in_"]) {
        define(['$B', 'panel'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if (!global["$B"]) {
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    var $doc = $(window.document);
    var defaults = {
        animationSpeed: 10,
        animationEasing: 'swing',
        change: null,
        control: 'hue',
        defaultValue: '',
        letterCase: 'lowercase',
        opacity: true,
        update2Target: true,
        showCaret: false,
        position: 'bottom left',
        positionFix: undefined,
        onfocus: null,
        onStartFn: null,
        onEndFn: null,
        onHideFn: null,
        theme: 'default',
        buttons: ['transparent', "#ffffff",
        "#000000", "#aaaaaa", "#CCCCCC", "#dddddd", 
        "#FF0505", "#DE0D4F", "#FC05A1", "#F558E8", 
        "#1803FF", "#633AE0", "#A8A8FA", "#BECEFA", 
        "#03DE24", "#00EBE3", "#8EDB98", "#DBE803", 
        "#D8E062", "#E8EAAD", "#FAF0E6", "#A020F0",
        "#990033", "#FFC0CB", "#428BCA","#5CB85C" ,
        "#5BC0DE" ,"#8B6D38","#0376F0" ,"#878F97" , 
        "#6C757D","#F7F4F8","#F3DEDE","#303133","#E4E7ED","#E1F3D8"
        ] 
    };

    function keepWithin(value, min, max) {
        if (value < min) {
            value = min;
        }
        if (value > max) {
            value = max;
        }
        return value;
    }
    function hsb2rgb(hsb) {
        var rgb = {};
        var h = Math.round(hsb.h);
        var s = Math.round(hsb.s * 255 / 100);
        var v = Math.round(hsb.b * 255 / 100);
        if (s === 0) {
            rgb.r = rgb.g = rgb.b = v;
        } else {
            var t1 = v;
            var t2 = (255 - s) * v / 255;
            var t3 = (t1 - t2) * (h % 60) / 60;
            if (h === 360) {
                h = 0;
            }
            if (h < 60) {
                rgb.r = t1;
                rgb.b = t2;
                rgb.g = t2 + t3;
            } else if (h < 120) {
                rgb.g = t1;
                rgb.b = t2;
                rgb.r = t1 - t3;
            } else if (h < 180) {
                rgb.g = t1;
                rgb.r = t2;
                rgb.b = t2 + t3;
            } else if (h < 240) {
                rgb.b = t1;
                rgb.r = t2;
                rgb.g = t1 - t3;
            } else if (h < 300) {
                rgb.b = t1;
                rgb.g = t2;
                rgb.r = t2 + t3;
            } else if (h < 360) {
                rgb.r = t1;
                rgb.g = t2;
                rgb.b = t1 - t3;
            } else {
                rgb.r = 0;
                rgb.g = 0;
                rgb.b = 0;
            }
        }
        return {
            r: Math.round(rgb.r),
            g: Math.round(rgb.g),
            b: Math.round(rgb.b)
        };
    }
    function rgb2hex(rgb) {
        var hex = [
            rgb.r.toString(16),
            rgb.g.toString(16),
            rgb.b.toString(16)
        ];
        $.each(hex, function (nr, val) {
            if (val.length === 1) {
                hex[nr] = '0' + val;
            }
        });
        return '#' + hex.join('');
    }

    function hsb2hex(hsb) {
        return rgb2hex(hsb2rgb(hsb));
    }

    function hex2hsb(hex) {
        var hsb = rgb2hsb(hex2rgb(hex));
        if (hsb.s === 0) {
            hsb.h = 360;
        }
        return hsb;
    }

    function rgb2hsb(arg) {
        var rgb = arg;
        var hsb = {
            h: 0,
            s: 0,
            b: 0
        };
        var min = Math.min(rgb.r, rgb.g, rgb.b);
        var max = Math.max(rgb.r, rgb.g, rgb.b);
        var delta = max - min;
        hsb.b = max;
        hsb.s = max !== 0 ? 255 * delta / max : 0;
        if (hsb.s !== 0) {
            if (rgb.r === max) {
                hsb.h = (rgb.g - rgb.b) / delta;
            } else if (rgb.g === max) {
                hsb.h = 2 + (rgb.b - rgb.r) / delta;
            } else {
                hsb.h = 4 + (rgb.r - rgb.g) / delta;
            }
        } else {
            hsb.h = -1;
        }
        hsb.h *= 60;
        if (hsb.h < 0) {
            hsb.h += 360;
        }
        hsb.s *= 100 / 255;
        hsb.b *= 100 / 255;
        return hsb;
    }

    function hex2rgb(hex) {
        hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
        return {
            r: hex >> 16,
            g: (hex & 0x00FF00) >> 8,
            b: (hex & 0x0000FF)
        };
    }

    function parseHex(string, expand) {
        string = string.replace(/[^A-F0-9]/ig, '');
        if (string === undefined || string === "") {
            return "";
        }
        var len = string.length;
        var diff = 6 - len,
            lastChar;
        if (diff) {
            lastChar = string[len - 1];
        }
        while (diff > 0) {
            string += lastChar;
            diff--;
        }
        return '#' + string;
    }

    function convertCase(string, letterCase) {
        return letterCase === 'uppercase' ? string.toUpperCase() : string.toLowerCase();
    }

    function getCoords(picker, container) {
        var left, top;
        if (!picker.length || !container) {
            return null;
        }
        left = picker.offset().left;
        top = picker.offset().top;
        return {
            x: left - container.offset().left + (picker.outerWidth() / 2),
            y: top - container.offset().top + (picker.outerHeight() / 2)
        };
    }
    /***
     * css =  {hex:,opacity:}
     * **/
    function updateFromInput(css) {
        var hex = css["hex"],
            hsb,
            opacity = css["opacity"],
            x, y, r, phi,
            minicolors = this.jqObj,
            settings = this.opts,
            swatch = minicolors.find('.k_minicolors_swatch'),
            grid = minicolors.find('.k_minicolors_grid'),
            slider = minicolors.find('.k_minicolors_slider'),
            opacitySlider = minicolors.find('.minicolors_opacity_slider'),
            gridPicker = grid.find('[class$=_picker]'),
            sliderPicker = slider.find('[class$=_picker]'),
            opacityPicker = opacitySlider.find('[class$=_picker]');

        if (!hex) {
            hex = convertCase(parseHex(settings.defaultValue, true), settings.letterCase);
        }
        hsb = hex2hsb(hex);

        if (settings.opacity) {
            if (isNaN(opacity)) {
                opacity = 1;
            }
            swatch.find('SPAN').css('opacity', opacity);
            y = keepWithin(opacitySlider.height() - (opacitySlider.height() * opacity), 0, opacitySlider.height());
            opacityPicker.css('top', y + 'px');
        }

        swatch.find('SPAN').css('backgroundColor', hex);

        var _pos;
        switch (settings.control) {
            case 'wheel':

                r = keepWithin(Math.ceil(hsb.s * 0.75), 0, grid.height() / 2);
                phi = hsb.h * Math.PI / 180;
                x = keepWithin(75 - Math.cos(phi) * r, 0, grid.width());
                y = keepWithin(75 - Math.sin(phi) * r, 0, grid.height());
                _pos = {
                    top: y + 'px',
                    left: x + 'px'
                };

                y = 150 - (hsb.b / (100 / grid.height()));
                if (hex === '') {
                    y = 0;
                }
                sliderPicker.css('top', y + 'px');

                slider.css('backgroundColor', hsb2hex({
                    h: hsb.h,
                    s: hsb.s,
                    b: 100
                }));
                break;

            case 'saturation':
                x = keepWithin((5 * hsb.h) / 12, 0, 150);
                y = keepWithin(grid.height() - Math.ceil(hsb.b / (100 / grid.height())), 0, grid.height());
                _pos = {
                    top: y + 'px',
                    left: x + 'px'
                };
                y = keepWithin(slider.height() - (hsb.s * (slider.height() / 100)), 0, slider.height());
                sliderPicker.css('top', y + 'px');

                slider.css('backgroundColor', hsb2hex({
                    h: hsb.h,
                    s: 100,
                    b: hsb.b
                }));
                minicolors.find('.minicolors-grid-inner').css('opacity', hsb.s / 100);
                break;

            case 'brightness':

                x = keepWithin((5 * hsb.h) / 12, 0, 150);
                y = keepWithin(grid.height() - Math.ceil(hsb.s / (100 / grid.height())), 0, grid.height());
                _pos = {
                    top: y + 'px',
                    left: x + 'px'
                };
                y = keepWithin(slider.height() - (hsb.b * (slider.height() / 100)), 0, slider.height());
                sliderPicker.css('top', y + 'px');

                slider.css('backgroundColor', hsb2hex({
                    h: hsb.h,
                    s: hsb.s,
                    b: 100
                }));
                minicolors.find('.minicolors-grid-inner').css('opacity', 1 - (hsb.b / 100));
                break;

            default:
                x = keepWithin(Math.ceil(hsb.s / (100 / grid.width())), 0, grid.width());
                y = keepWithin(grid.height() - Math.ceil(hsb.b / (100 / grid.height())), 0, grid.height());
                _pos = {
                    top: y + 'px',
                    left: x + 'px'
                };
                y = keepWithin(slider.height() - (hsb.h / (360 / slider.height())), 0, slider.height());
                sliderPicker.css('top', y + 'px');
                grid.css('backgroundColor', hsb2hex({
                    h: hsb.h,
                    s: 100,
                    b: 100
                }));
                break;
        }
        gridPicker.css(_pos);
    }

    function updateControl(input, target) {
        var hue, saturation, brightness, x, y, r, phi,
            hex,
            opacity = input.attr('data-opacity'),
            minicolors = this.jqObj,
            settings = this.opts,
            swatch = minicolors.find('.k_minicolors_swatch'),

            grid = minicolors.find('.k_minicolors_grid'),
            slider = minicolors.find('.k_minicolors_slider'),
            opacitySlider = minicolors.find('.k_minicolors_opacity_slider'),

            gridPicker = grid.find('[class$=_picker]'),
            sliderPicker = slider.find('[class$=_picker]'),
            opacityPicker = opacitySlider.find('[class$=_picker]'),

            gridPos = getCoords(gridPicker, grid),
            sliderPos = getCoords(sliderPicker, slider),
            opacityPos = getCoords(opacityPicker, opacitySlider),
            fontColor = "#000000";

        if (input.val) {
            hex = input.val();
        }

        if (target.is('.k_minicolors_grid, .k_minicolors_slider')) {
            switch (settings.control) {
                case 'wheel':
                    x = (grid.width() / 2) - gridPos.x;
                    y = (grid.height() / 2) - gridPos.y;
                    r = Math.sqrt(x * x + y * y);
                    phi = Math.atan2(y, x);
                    if (phi < 0) {
                        phi += Math.PI * 2;
                    }
                    if (r > 75) {
                        r = 75;
                        gridPos.x = 69 - (75 * Math.cos(phi));
                        gridPos.y = 69 - (75 * Math.sin(phi));
                    }
                    saturation = keepWithin(r / 0.75, 0, 100);
                    hue = keepWithin(phi * 180 / Math.PI, 0, 360);
                    brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
                    hex = hsb2hex({
                        h: hue,
                        s: saturation,
                        b: brightness
                    });
                    slider.css('backgroundColor', hsb2hex({
                        h: hue,
                        s: saturation,
                        b: 100
                    }));
                    break;
                case 'saturation':
                    hue = keepWithin(parseInt(gridPos.x * (360 / grid.width()), 10), 0, 360);
                    saturation = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
                    brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
                    hex = hsb2hex({
                        h: hue,
                        s: saturation,
                        b: brightness
                    });
                    slider.css('backgroundColor', hsb2hex({
                        h: hue,
                        s: 100,
                        b: brightness
                    }));
                    minicolors.find('.k_minicolors_grid_inner').css('opacity', saturation / 100);
                    break;
                case 'brightness':
                    hue = keepWithin(parseInt(gridPos.x * (360 / grid.width()), 10), 0, 360);
                    saturation = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
                    brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
                    hex = hsb2hex({
                        h: hue,
                        s: saturation,
                        b: brightness
                    });
                    slider.css('backgroundColor', hsb2hex({
                        h: hue,
                        s: saturation,
                        b: 100
                    }));
                    minicolors.find('.k_minicolors_grid_inner').css('opacity', 1 - (brightness / 100));
                    break;
                default:
                    hue = keepWithin(360 - parseInt(sliderPos.y * (360 / slider.height()), 10), 0, 360);
                    saturation = keepWithin(Math.floor(gridPos.x * (100 / grid.width())), 0, 100);
                    brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
                    hex = hsb2hex({
                        h: hue,
                        s: saturation,
                        b: brightness
                    });
                    grid.css('backgroundColor', hsb2hex({
                        h: hue,
                        s: 100,
                        b: 100
                    }));
                    break;
            }
        }
        if (target.is('.k_minicolors_opacity_slider')) {
            if (settings.opacity) {
                opacity = parseFloat(1 - (opacityPos.y / opacitySlider.height())).toFixed(2);
            } else {
                opacity = 1;
            }
            if (settings.opacity) {
                input.attr('data-opacity', opacity);
            }
        }
        swatch.find('SPAN').css({
            backgroundColor: hex,
            opacity: opacity
        });
        doChange.call(this, hex, opacity, fontColor);
    }

    function doChange(hex, opacity, fontColor) {
        if(hex.indexOf("rgb") > -1){
            hex = hex.toHexColor();
        }
        var input = this.target;
        var settings = this.opts,
            lastChange = input.data('minicolors-lastChange');
        fontColor =    this.getContrastColor(hex);
        var _css = {
            "color": fontColor,
            "background-color": hex,
            filter: 'alpha(opacity=' + opacity * 100 + ')',
            "-moz-opacity": opacity,
            "-khtml-opacity": opacity,
            opacity: opacity
        };
        this.values = _css;
        if (settings.update2Target) {
            this.target.css(_css);
        }
        if (this.target[0].tagName === "INPUT") {
            this.target.val(hex);
        }
        if (!lastChange || lastChange.hex !== hex || lastChange.opacity !== opacity) {
            input.data('minicolors-lastChange', {
                hex: hex,
                opacity: opacity
            });
            if(hex !== "transparent"){
                this.currentColor = hex;    
            }                   
            if (settings.change) {
                settings.change.call(input, hex, opacity);
            }
        }
    }

    function move(target, event, animate) {
        if (!this.target) {
            return;
        }
        var input = this.target,
            _this = this,
            settings = this.opts,
            Picker = target.find('[class$=_picker]'),
            offsetX = target.offset().left,
            offsetY = target.offset().top,
            x = Math.round(event.pageX - offsetX),
            y = Math.round(event.pageY - offsetY),
            duration = animate ? settings.animationSpeed : 0,
            wx, wy, r, phi;

        if (event.originalEvent.changedTouches) {
            x = event.originalEvent.changedTouches[0].pageX - offsetX;
            y = event.originalEvent.changedTouches[0].pageY - offsetY;
        }

        if (x < 0) {
            x = 0;
        }
        if (y < 0) {
            y = 0;
        }
        if (x > target.width()) {
            x = target.width();
        }
        if (y > target.height()) {
            y = target.height();
        }

        if (target.parent().is('.k_minicolors_slider_wheel') && Picker.parent().is('.k_minicolors_grid')) {
            wx = 75 - x;
            wy = 75 - y;
            r = Math.sqrt(wx * wx + wy * wy);
            phi = Math.atan2(wy, wx);
            if (phi < 0) {
                phi += Math.PI * 2;
            }
            if (r > 75) {
                r = 75;
                x = 75 - (75 * Math.cos(phi));
                y = 75 - (75 * Math.sin(phi));
            }
            x = Math.round(x);
            y = Math.round(y);
        }
        if (target.is('.k_minicolors_grid')) {
            Picker.stop(true).animate({
                top: y + 'px',
                left: x + 'px'
            }, duration, settings.animationEasing, function () {
                updateControl.call(_this, input, target);
            });
        } else {
            Picker.stop(true).animate({
                top: y + 'px'
            }, duration, settings.animationEasing, function () {
                updateControl.call(_this, input, target);
            });
        }
        return false;
    }

    function ColorPicker(jqObj, opts) {
        $B.extend(this, ColorPicker); //继承父类        
        this.lastColors = [];//最近使用的颜色
        this.colorCookieName = "colorpicker_";
        var seft = this;
        this.opts = $.extend(true, {}, defaults, opts);
        if (jqObj) {
            this.setTarget(jqObj);
        }
        this.jqObj = $('<div tabindex="0" class="k_minicolors k_box_shadow" />')
            .addClass('k_minicolors_theme_' + this.opts.theme)
            .toggleClass('k_minicolors_with_opacity', this.opts.opacity).appendTo($("body"));
        this.jqObj.append(
            '<div tabindex="0" class="k_minicolors_panel  k_minicolors_slider_' + this.opts.control + '">' +
            '<div tabindex="0" class="k_minicolors_slider"><div class="k_minicolors_picker"></div>' +
            '</div><div tabindex="0"  class="k_minicolors_opacity_slider"><div  tabindex="0"  class="k_minicolors_picker"></div>' +
            '</div><div  tabindex="0" class="k_minicolors_grid"><div  tabindex="0"  class="k_minicolors_grid_inner"></div>' +
            '<div tabindex="0" class="k_minicolors_picker"><div  tabindex="0" ></div></div></div></div>');
        if (this.opts.showCaret) {
            $("<div style='height:12px;width:100%;margin-top:-12px;padding-left:2px'><i style='font-size:16px;color:#3E4043;line-height:12px;position:relative;top:1px' class='fa fa-up-dir'></i></div>").prependTo(this.jqObj);
        }
        this.isBodyClick = true;
        this.jqObj.children(".k_minicolors_panel").mousedown(function () {
            $doc.data("_colorpicker_", seft);
            $doc.on('mousedown.k_minicolors touchstart.k_minicolors', '.k_minicolors_grid, .k_minicolors_slider, .k_minicolors_opacity_slider',
                function (event) {
                    var target = $(this);
                    var _this = $doc.data('_colorpicker_');
                    $doc.data('k_minicolors_target', target);
                    move.call(_this, target, event, true);
                    if (_this.opts.onStartFn) {
                        _this.opts.onStartFn();
                    }
                }).on('mousemove.k_minicolors touchmove.k_minicolors',
                    function (event) {
                        var _this = $doc.data('_colorpicker_');
                        var target = $doc.data('k_minicolors_target');
                        if (target) {
                            move.call(_this, target, event);
                        }
                    }).on('mouseup.k_minicolors touchend.k_minicolors',
                        function (event) {
                            var _this = $doc.data('_colorpicker_');
                            if (_this) {
                                var target = $doc.data('k_minicolors_target');
                                if (target) {
                                    $(this).removeData('k_minicolors_target');
                                    if (_this.opts.onEndFn) {
                                        _this.opts.onEndFn();
                                    }
                                }
                                _this.isBodyClick = false;
                                setTimeout(function () {
                                    _this.isBodyClick = true;
                                }, 300);
                            }
                        });

        }).mouseup(function () {
            $doc.off('mousedown.k_minicolors touchstart.k_minicolors', '.k_minicolors_grid, .k_minicolors_slider, .k_minicolors_opacity_slider');
            setTimeout(function () {
                $doc.removeData("_colorpicker_");
            }, 300);
        });
        this.colorsBtnWrap = $("<div  tabindex='0'  class='k_minicolors_color_buttons'></div>").appendTo(this.jqObj);
        function _click() {
            seft.target.removeData('minicolors-lastChange');
            seft.buttonClick($(this).css("background-color"));
        }
        for (var i = 0, len = this.opts.buttons.length; i < len; ++i) {
            var $btn = $("<div  tabindex='0' style='background-color:" + this.opts.buttons[i] + "'></div>")
                .appendTo(this.colorsBtnWrap)
                .click(_click);
            if (i === 0) {
                $btn.addClass("k_mincolors_btn_nonecolor");
            }
        }
        if (this.opts.onfocus) {
            this._bindFocus(this.jqObj);
        }
        if (this.opts.mouseenter) {
            this.jqObj.mouseenter(this.opts.mouseenter);
        }
        if (this.opts.clickHide) {
            (function (_this) {
                var nsId = $B.getUUID();
                $("body").on("click."+nsId,function(){
                    if (_this.isBodyClick) {
                        _this.hide();
                    }else{
                        $(this).off("."+nsId);
                    }
                });               
            })(seft);
        }
        //从cookie恢复最近使用的5个颜色
        var tmp = $B.getCookie(this.colorCookieName);
        if(tmp !== ""){
            var colors = tmp.split(",");
            this.lastColors = colors;
            this._setLastColors();
        }
    }
    ColorPicker.prototype = {
        constructor: ColorPicker,
        /**获取高对比度颜色**/
        getContrastColor:function(value){
            if(!value){
                return 'rgb(105, 118, 166)';
            }
            var rgb = value;
            if (value.toLowerCase().indexOf("rgb") < 0) {
                rgb = hex2rgb(value);
            }
            rgb.r = 255- rgb.r;
            rgb.g = 255- rgb.g;
            rgb.b = 255- rgb.b;
            return ['rgb(',rgb.r,',',rgb.g ,',',rgb.b,')'].join('');         
        },
        _bindFocus: function (jqTag) {
            var _this = this;
            var _onfocus = function (e) {
                _this.opts.onfocus();
            };
            jqTag.on("focus", _onfocus);
            jqTag.children().each(function () {
                _this._bindFocus($(this));
            });
        },
        setTarget: function (jqObj) {
            this.target = jqObj.css("background-image", "none").addClass("k_color_picker_cls");
            if (!this.target.data("color_picker_fire")) {
                this.target.on("click.colorpicker", function (e) {
                    var $t = $(this);
                    if ($t.data("break")) {
                        return;
                    }
                    var picker = $t.data("picker");
                    if (picker.isShow()) {
                        picker.hide();
                    } else {
                        picker.show();
                    }
                }).data("picker", this);
                this.target.data("color_picker_fire", true);
            }
            return this;
        },
        unbindTarget: function () {
            if (this.target) {
                this.target.removeData("color_picker_fire");
                this.target.removeData("picker");
                this.target.off("click.colorpicker").removeClass("k_color_picker_cls");
                this.target = undefined;
            }
            return this;
        },
        setPosition: function (ofs) {
            ofs.top = ofs.top + this.target.outerHeight();
            if (this.opts.positionFix) {
                if (this.opts.positionFix.top) {
                    ofs.top = ofs.top + this.opts.positionFix.top;
                }
                if (this.opts.positionFix.left) {
                    ofs.left = ofs.left + this.opts.positionFix.left;
                }
            }
            this.jqObj.css(ofs).show();
            return this;
        },
        hideImd: function (isUnbind) {
            var _this = this;
            if (isUnbind) {
                _this.unbindTarget();
            }
            _this.jqObj.hide();
            if (_this.opts.onHideFn) {
                _this.opts.onHideFn();
            }
        },
        hide: function (isUnbind) {
            if(this.currentColor){
                if(this.currentColor.indexOf("rgb") > -1){
                    this.currentColor = this.currentColor.toHexColor();
                }
                this.currentColor = this.currentColor.toLowerCase();
                var i = 0 ,len ,go = true;
                for( i = 0 ,len = this.lastColors.length ; i < len ;++i){
                    if(this.currentColor === this.lastColors[i]){
                        go = false;
                        break;
                    }
                }
                if(go){
                    //记住最近用的5种颜色
                    if(this.lastColors.length === 5){
                        this.lastColors.pop();                          
                    }
                    this.lastColors.unshift(this.currentColor); 
                    this._setLastColors();
                }                
            }
            this.currentColor = undefined;
            clearTimeout(this["hidetimer"]);
            var _this = this;
            this["hidetimer"] = setTimeout(function () {
                if (isUnbind) {
                    _this.unbindTarget();
                }
                _this.jqObj.slideUp(100, function () {
                    if (_this.opts.onHideFn) {
                        _this.opts.onHideFn();
                    }
                });
            }, 100);
            return this;
        },
        _setLastColors:function(){
            //更新 this.colorsBtnWrap
            var lastBtn = this.colorsBtnWrap.children().last();
            for(var i = 0 ,len = this.lastColors.length ; i < len ;++i){
                lastBtn.css("background-color" , this.lastColors[i]);
                lastBtn = lastBtn.prev();
            }
            var lastColorstr = this.lastColors.join(",");
            $B.writeCookie(this.colorCookieName , lastColorstr ,3);
        },
        show: function (target, offset) {
            if (this.target && target && this.target[0] === target[0]) {
                return;
            }
            clearTimeout(this["showtimer"]);
            var _this = this;
            if (target) {
                target.data("break", true);
                _this.setTarget(target);
            }
            var ofs = _this.target.offset();
            if (offset) {
                if (offset.top) {
                    ofs.top = ofs.top + offset.top;
                }
                if (offset.left) {
                    ofs.left = ofs.left + offset.left;
                }
            }
            this["showtimer"] = setTimeout(function () {
                _this.setPosition(ofs);
                _this.target.removeData("break");
            }, 200);
            return this;
        },
        isShow: function () {
            var dis = this.jqObj.css("display");
            return dis === "block";
        },
        buttonClick: function (color) {
            doChange.call(this, color, 1, undefined);           
            if (typeof color === "string") {
                if (color.toLowerCase().indexOf("rgb") > -1) {
                    color = color.toHexColor();
                }
                var value = {
                    "hex": color
                };
                updateFromInput.call(this, value);
            }            
            return this;
        },
        /**
         * {hex:,opacity:}
         * **/
        setValue: function (value, invokeChange) {
            if (typeof value === "string") {
                if (value.toLowerCase().indexOf("rgb") > -1) {
                    value = value.toHexColor();
                }
                value = {
                    "hex": value
                };
            }
            updateFromInput.call(this, value);
            if (this.target && (typeof invokeChange === "undefined" || invokeChange)) {
                doChange.call(this, value.hex, 1, undefined);
            }
            return this;
        },
        getValue: function () {
            return this.values;
        }
    };
    $B["ColorPicker"] = ColorPicker;
    return ColorPicker;
}));